<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>dragbox</title>
    <script src="https://gw.alipayobjects.com/os/antv/pkg/_antv.g6-3.2.0/build/g6.js"></script>
    <script src="js/jquery.js"></script>
    <script src="js/addTool.js"></script>

    <link type="text/css" href="css/index.css" rel="stylesheet">

    <!--uuid-->
    <script>
        let uuid = (randomLength) => {
            return 'a' + Number(Math.random().toString().substr(3, randomLength) + Date.now()).toString(36)
        };

        // 把可选项中的数据放到data里面
        let bindData2Model = (model) => {
            model.change.forEach(opt => {
                let data = '';
                if (opt.default) {
                    data = opt.default
                } else if (opt.av) {
                    data = opt.av[0]
                }

                model.data[opt.name] = data
            })
            model.data.att = ''
            model.data.name = model.label
        };

        // 添加点用的函数
        let defaultAddNode = (label, data, option) => {
            let model = {
                id: uuid(),   // 唯一ID
                label: label,   // 上面写的字（标签），
                data: data,    // 可选数据项，可以被原封不动储存下来
                x: 100,
                y: 200,
            };
            for (let i in option) {
                model[i] = option[i]
            }

            bindData2Model(model)
            graph.addItem('node', model)
        };
        // 在创建连接时会用到
        let connFun = (fromNode, toNode) => {
            return [{
                label: 'conn1',
                data: {}, // 额外的data
                option: {
                    change: [
                        {
                            name: '连接强度',
                            kind: 't',
                            default: '100%'
                        },
                        {
                            name: "连接重要性",
                            kind: 'ch',
                            av: ['高', '低']
                        }
                    ]
                }

            }, {
                label: 'conn2'
            }]
        }

        let selLineDiv = undefined    //连线用的框框
        let removeLineDiv = () => {
            if (selLineDiv) {
                selLineDiv.remove()
                selLineDiv = undefined
            }
        }


    </script>


    <!--画工具栏用的数据-->
    <script>
        // 所有可使用的拖拽块（工具栏）
        let toolData = [
            {
                name: '查看',
                onclick: () => {
                    graph.setMode('view')
                }
            },
            {
                name: '编辑',
                onclick: () => {
                    // console.log('cli');
                    graph.setMode('edit')
                }
            },
            {
                // 所有组件的所有数据都会放在data里面
                name: '加一个点',
                img: 'img/比较点.png',
                onclick() {
                    defaultAddNode('love', {
                            src: 'img/比较点.png',

                        }, {
                            change: [{
                                name: '传递函数',
                                kind: 't',
                                default: 'x',
                            }]
                        }
                    )
                },


            }]
    </script>

</head>
<body>

<div class="topBar">
    <span id="save-all-button">保存</span>
    <span id="load-all-button">加载</span>
</div>

<div class="downside-box">
    <!--图元表-->
    <div class="list" id="toolDiv">
        <div class="top">工具内个栏</div>
        <ul id="toolRoot"></ul>
    </div>

    <!--展示框-->
    <div id="myDiv" class="showDiv"></div>

    <!--详细栏-->
    <div class="detailDiv" id="detail">
        <div id="det-title">详细</div>
        <ul>
            <li id="det-name" style="display: none">
                <p>名称：</p>
                <p style="text-align: center;"></p>
            </li>
            <li id="det-text" style="display: none">
                <p>标题：</p>
                <input>
            </li>
            <li class="det-one-line" id="det-X" style="display: none">
                <p>X:</p>
                <input>
            </li>
            <li class="det-one-line" id="det-Y" style="display: none">
                <p>Y:</p>
                <input>
            </li>

            <li id="det-att" style="display: none">
                <p>备注：</p>
                <textarea></textarea>
            </li>
        </ul>
        <div id="det-button" style="display: none">
            <button id="save-button">保存</button>
            <button style="margin-left: 10%" id="del-button">删除</button>
        </div>
    </div>
</div>


<script>
    //调用showtool函数画左边工具框,并设置竖直位置修正
    let tmp = $('#toolDiv').offset()
    showTool(toolData, 0, $('#toolRoot'), {
        top: tmp.top + 2,
        left: tmp.left + 2
    })

    let saveAll = $('#save-all-button')
    saveAll.on('mouseover', () => {
        console.log('1234')
    })


    // 右边的详细框
    let det = {
        name: $('#det-name'), //组件名,
        text: $('#det-text'), //组件显示文字
        X: $('#det-X'),
        Y: $('#det-Y'),
        att: $('#det-att'), //组件备注
        butt: $('#det-button')
    };
    let detUl = $('#detail ul'); // 整个的右边详细框
    let otherDet = {};  // 非必须的详细框的$对象，在每个model的change里面

    //隐藏详细栏中全部的小框
    let hideAllDet = () => {
        let list = detUl[0].children;
        for (let i in det) {
            det[i].css({
                display: 'none'
            })
        }
        for (let i in otherDet) {
            otherDet[i].remove()
        }
    }

</script>

<!--使用G6来画图-->
<script>
    let graphCantainer = $('#myDiv');//获取图的容器
    // console.log(graphCantainer.innerHeight,graphCantainer.innerWidth)
    // 实例化G6
    let graph = new G6.Graph({
        container: "myDiv",
        width: graphCantainer.innerWidth(),
        height: graphCantainer.innerHeight(),
        fitView: true, // 自适应图大小
        // 交互模式
        modes: {
            default: [],
            view: ['show-detail', 'drag-canvas', 'zoom-canvas'], // 允许拖拽画布、放缩画布、拖拽节点
            edit: ['drag-canvas', 'zoom-canvas', 'drag-node', 'show-detail', 'add-edge'],
        },
        nodeStateStyles: {
            click: {
                stroke: 'black',
                lineWidth: 2
            }
        },
        edgeStateStyles: {
            click: {
                stroke: 'red',
                lineWidth: 2
            }
        }
    })

    // 将model对应地展示到详细栏里
    let showDet = (e) => {
        let model = e.item.getModel();
        let change = model.change || {};
        for (let i in change) {
            let li = $('<li>').attr('id', 'det-' + change[i].name).appendTo(detUl);
            li.append($('<p>').text(change[i].name));
            if (change[i].kind === 't') {// 文字
                $('<input>').val(model.data[change[i].label]).appendTo(li)
            } else { // 选择
                let select = $('<select>').appendTo(li);
                let selectIndex = 0;
                for (let j in change[i].av) {
                    let text = change[i].av[j]; // 关键字名
                    let option = $('<option value="' + text + '">').text(text); // 一个选项$对象
                    if (text === model.data[change[i].name]) {
                        selectIndex = j;
                        console.log(j, select);
                    }
                    option.appendTo(select)
                }
                select[0].selectedIndex = selectIndex
            }
            otherDet[change[i].name] = li
        }
        det.name.css({display: ''});
        det.text.css({display: ''});
        det.att.css({display: ''});
        det.name[0].children[1].innerHTML = model.data.name;  //组件名，表示组件种类，不可变
        det.text[0].children[1].value = model.label;   // 组件标签，表示组件昵称，可变，默认为组件名
        det.att[0].children[1].value = model.data.att;
        if (e.item.getType() === 'node') {
            // 块块出现
            det.X.css({display: ''});
            det.Y.css({display: ''});
            // 块块加字
            det.X[0].children[1].value = model.x;
            det.Y[0].children[1].value = model.y;
        }

    }

    // 取消所有线和点的选择
    let cancealSelect = () => {
        let clickNodes = graph.findAllByState('node', 'click');
        clickNodes.forEach(cn => {
            graph.setItemState(cn, 'click', false);
        });
        let clickEdges = graph.findAllByState('edge', 'click');
        clickEdges.forEach(cn => {
            graph.setItemState(cn, 'click', false);
        });
    }

    // 点击时选中并在详细栏中展示,并在点击背景时消除连线框
    G6.registerBehavior('show-detail', {
        getEvents() {
            return {
                "node:click": "clickNode",
                "canvas:click": "clickCanvas",
                "edge:click": 'clickEdge'
            }
        },
        clickNode(e) {
            // 先将所有当前有 click 状态的节点的 click 状态置为 false
            cancealSelect();
            graph.setItemState(e.item, 'click', true);
            showDet(e);
        },
        clickEdge(e) {
            cancealSelect()
            graph.setItemState(e.item, 'click', true);
            showDet(e);
        },

        clickCanvas(e) {
            cancealSelect();
            removeLineDiv();
            // if (selLineDiv) {
            //     selLineDiv.remove()
            //     selLineDiv = undefined
            // }
            hideAllDet();
        }
    });


    G6.registerBehavior('add-edge', {
        fromNode: undefined,  // 连线时第一个被选择的点
        getEvents() {
            return {
                "node:mouseenter": "enterNode",
                "node:click": "clickNode",
                "canvas:click": "clickCanvas"
            }
        },
        // 鼠标进入方块来连线
        enterNode(e) {
            removeLineDiv();
            let toNode = e.item;    // 目标点，item对象
            if (!this.fromNode) {
                return
            }
            let allowList = connFun(this.fromNode, toNode);
            if (!allowList) {
                return
            }
            console.log(allowList);
            selLineDiv = $('<div class="selectLine">')
                .css({
                    // 获取组件绝对位置的语句
                    top: e.clientY,
                    left: e.clientX
                })
                .appendTo($('body'));

            // 添加选项
            for (let i in allowList) {
                selLineDiv.append(
                    $('<div>').text(allowList[i].label)
                        .on('click', () => {
                            let option = allowList[i].option
                            let model = {
                                label:allowList[i].label||"",
                                source: this.fromNode.getModel().id,
                                target: toNode.getModel().id,
                                data: allowList[i].data,
                                style: {
                                    endArrow: true,
                                    lineWidth: 2,
                                },
                            };
                            model.data.name=model.data.text||model.label;
                            for (let j in option) {
                                model[j] = option[j]
                            }
                            bindData2Model(model);
                            // 添加线
                            graph.addItem('edge', model)
                            //删除框
                            removeLineDiv()
                        })
                );
                console.log(i, selLineDiv)
            }

            // 删除连线选择小块
            selLineDivTimer = setTimeout(removeLineDiv, 5000)
        },
        clickNode(e) {
            // 先将所有当前有 click 状态的节点的 click 状态置为 false
            console.log('click', e)
            this.fromNode = e.item
            let model = this.fromNode.getModel();

        },
        clickCanvas(e) {
            this.fromNode = undefined
        }

    })

    graph.setMode('view')
</script>


</body>
</html>